App.require(function () {
    var app = App.getCurrent();

    app.defineComponent("str-range", {
        set value(val) {
            if (val === this.property.value) return;
            var property = this.property,
                domList = this.domList,
                label = domList.label;
            property.value = val;
            domList.input.value = val;
            label.style.setProperty("--percent", (100 * (val - property.min) / (property.max - property.min)).toFixed(2) + "%");
            if (property.tip) {
                label.firstElementChild.dataset.value = val;
            }
        },
        get value() {
            return parseInt(this.property.value);
        },
        set min(val) {
            if (this.property.min === val) return;
            this.property.min = val;
            input.min = val;
            if (this.property.value < val) this.value = val;
        },
        get min() {
            return parseInt(this.property.min);
        },
        set max(val) {
            if (this.property.max === val) return;
            var property = this.property,
                label = this.domList.label,
                input = this.domList.input;
            property.max = val;
            input.max = val;

            label.style.setProperty("--percent", (100 * (property.value - property.min) / (property.max - property.min)).toFixed(2) + "%");
            if (val < property.value) this.value = val;
        },
        set form(value) {
            this.property.form = value;
            this.domList.input.form = value;
        },
        get form() {
            return this.property.form;
        },
        get max() {
            return parseInt(this.property.max);
        },
        set name(val) {
            if (this.property.name === val) return;
            this.property.name = val;
            var input = this.domList.input,
                label = this.domList.label;
            input.name = val;
            input.id = val;
            label.htmlFor = val;
        },
        get name() {
            return this.property.name;
        },
        get disabled() {
            return this.property.disabled;
        },
        set disabled(value) {
            value = value ? "disabled" : "";
            if (value === this.property.disabled) return;
            if (value) {
                this.domList.input.setAttribute("disabled", "");
            }
            else {
                this.domList.input.removeAttribute("disabled");
            }
            this.property.disabled = value;
        },
        get step() {
            return parseInt(this.property.step);
        },
        set step(value) {
            this.domList.input.step = value;
            this.property.step = value;
        },
        get readonly() {
            return this.property.readonly;
        },
        set readonly(value) {
            value = value ? "readonly" : "";
            if (value === this.property.readonly) return;
            if (value) {
                this.domList.input.setAttribute("readonly", "");
            }
            else {
                this.domList.input.removeAttribute("readonly");
            }
            this.property.readonly = value;
        },
        get autofocus() {
            return this.property.autofocus;
        },
        get tip() {
            return this.property.tip;
        },
        set tip(value) {
            value = !!value;
            if (value === this.property.tip) return;
            var label = this.domList.label,
                span = label.firstElementChild;
            if (value) {
                span.classname = "range-tip";
                span.dataset.value = this.property.value;
            }
            else {
                span.classname = "";
                span.dataset.value = "";
            }
            this.property.tip = value;
        },
        get className() {
            return this.property.class;
        },
        set className(value) {
            if (this.property.class == value) return;
            this.domList.container.className = value;
            this.property.class = value;
        },
        getDomObj: function () {
            this.attachDom("input", "input")
                .attachDom("[role='range']", "container")
                .attachDom("input+label", "label")
                .attachEvent("input", "focus", this.focusHandler, false)
                .attachEvent("input", "blur", this.blurHandler, false)
                .attachEvent("input", "change", this.changeHandler, false)
                .attachEvent("input", "input", this.inputHandler, false);
        },
        focusHandler: function (ev) {
            this.dispatchCustomEvent("rangefocus", {
                component: this,
                target: ev.currentTarget
            });
        },
        blurHandler: function (ev) {
            this.dispatchCustomEvent("rangeblur", {
                component: this,
                target: ev.currentTarget
            });
        },
        changeHandler: function (ev) {
            this.dispatchCustomEvent("rangechange", {
                component: this,
                target: ev.currentTarget
            });
        },
        inputHandler: function (ev) {
            var target = ev.target,
                property = this.property,
                label = this.domList.label;
            target.focus();
            property.value = target.value;
            label.style.setProperty("--percent", (100 * (property.value - property.min) / (property.max - property.min)).toFixed(2) + "%");

            if (property.tip) {
                label.firstElementChild.dataset.value = property.value;
            }
            this.dispatchCustomEvent("rangeinput", {
                component: this,
                target: ev.currentTarget
            });
        },
        computeDate: function () {
            var property = this.property;
            property.value = property.value || 0;
            property.step = property.step || 1;
            property.tip = typeof property.tip !== "undefined";
            property.form = property.form || "";
            property.class = property.class || "";
            property.disabled = typeof property.disabled !== "undefined" ? "disabled" : "";
            property.readonly = typeof property.readonly !== "undefined" ? "readonly" : "";
            property.name = property.name || this.uid;
            property.label = property.label || this.name;
            property.min = property.min || 0;
            property.max = property.max || 100;
            property.percent = (100 * (property.value - property.min) / (property.max - property.min)).toFixed(2) + "%";
            property.autofocus = typeof property.autofocus !== "undefined" ? "autofocus" : "";
        },
        render: function (next) {
            this.computeDate();
            this.fetch("index.html", function (text) {
                return next(this.renderHTML(text));
            })
        }
    })
});